/*Description
设计一个安全数组类模板Array<T>，其中包含数组的输入、输出、排序和查找等方法，使用三种类型的数据对其进行测试。
（1）设计构造函数Array<T>::Array(int n)，可动态分配n个T类型的存储空间；
（2）设计析构函数Array<T>::~Array()释放内存；
 (3）重载输入流运算符istream &operator>>(istream& in, Array<T>& arr)读入n个T类型数据；
（4）重载输出流运算符ostream &operator<<(ostream& out, const Array<T>& arr)输出n个T类型数据；
（5）重载[]运算符，若索引值i越界，则输出“Out of boundary”并退出程序，否则返回第i个数据元素；
（6）基于<algorithm>中的sort函数定义成员函数void Array<T>::sort()，实现数组排序；
（7）设计成员函数int Array<T>::search(T e)const，若查找成功返回非负索引值，否则返回-1；
（8）设计函数模板void Process(Array<T> &a)用于测试数组类模板。
*/
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<stdexcept>
using namespace std;
template <typename T>
class Array
{
 private:
   int size;
   T *a;
 
 public:
 //非模版函数？？？friend istream &operator>>(istream& in, Array<T>& arr);
 //直接使用类模板T，编译器会将友元函数当成一个普通的，非模板的函数声明
 template <typename U>   
 friend istream &operator>>(istream& in,Array<U>&arr);
 
 template <typename U>
 friend ostream &operator<<(ostream& out, const Array<U>&arr );
 //动态分配内存
 Array(int n)
 {
    size=n;
    a=new T[size];
 }
 //析构
 ~Array()
 {
    if(a!=nullptr)
    delete []a;//delete[]a写法
 }
//检验是否越界
T operator[](int i)const
{
  if(i<0||i>=size)
 {cout<<"Out Of Boundary"<<endl;
  exit(1);
 }
  else return a[i];
}

//sort函数
void sort()
{
   std::sort(a,a+size);
}

//search函数
int search (T e)const
{
   for(int i=0;i<size;++i)
   {
    if(a[i]==e)
    return i;
    }
    cout << "Element not found in array." << endl;
    return -1;
}

//process测试函数
void Process()
{
   cout<<"Enter "<<size<<" elements: ";
   cin>>*this;
   
   cout<<"Array contents: "<<*this<<endl;

   sort();
   cout<<"After sorting: "<<*this<<endl;
   
   T searchVal;
   cout<<"Enter a value to search: ";
   cin>>searchVal;
   int index=search(searchVal);
   if(index!=-1)
   cout<<"Found"<<endl;
   else cout<<"Not found"<<endl;
       
   try
   {
      cout<<"Inter an index"<<endl;
      int index;
      cin>>index;
      cout<<"Element at index"<<index<<" is "<<a[index]<<endl;
    }catch(const out_of_range&e)
    {
        cerr<<"Error: "<<e.what()<<endl;
    }
}//const char [10]和<T>与<<不匹配？？？
};
//类外定义函数，U要再说明
template<typename U>
istream &operator>>(istream& in, Array<U>& arr)
//第二个参数：函数可以接受任何以T为模版参数实例化出的Array对象
{
    
     for(int i=0;i<arr.size;++i)
     {
        in>>arr.a[i];
     }
     return in;//return in支持链式操作
   
 }
 template<typename U>
ostream &operator<<(ostream& out, const Array<U>& arr)
{
    
     for(int i=0;i<arr.size;++i)
     {
        out<<arr.a[i];
     }
     return out;
   
}
int main()
{
    
    string type;
    int n;

    cin >> type >> n;
    if (type=="int")
    {
        Array<int> a(n);
        a.Process();
    }
    else if (type=="double")
    {
        Array<double> a(n);
        a.Process();
    }
    else if (type=="string")
    {
        Array<string> a(n);
       a. Process();
    }
    else
        cout << "Input error!" << endl;

    return 0;
}

